package com.taomeishu.mailcrazy.seq;

import java.util.Arrays;

public class CharseqNumber {

	final static char[] digits = {
		'0' , '1' , '2' , '3' , '4' , '5' ,
		'6' , '7' , '8' , '9' , 'a' , 'b' ,
		'c' , 'd' , 'e' , 'f' , 'g' , 'h' ,
		'i' , 'j' , 'k' , 'l' , 'm' , 'n' ,
		'o' , 'p' , 'q' , 'r' , 's' , 't' ,
		'u' , 'v' , 'w' , 'x' , 'y' , 'z' ,
		'-' , '_',  '.'
	    };
	
	final static int MAX_RADIX = digits.length;
	
	final static int MIN_RADIX = 2;
	
	final static int[] chars = new int[128];
	
	static {
		for (int i = 0; i <= 9; ++i) {
			chars['0' + i] = i;
		}
		for (int i = 0; i <= 26; ++i) {
			chars['a' + i] = 10 + i;
		}
		chars['-'] = 36;
		chars['_'] = 37;
		chars['.'] = 38;
	}
	
	final static int digits_length = digits.length;
	
	private char[] buf = new char[64];
	
	public CharseqNumber() {
		
	}
	
	public CharseqNumber(String s) {
		if (s == null || s.length() == 0) {
			return;
		}
		for (int i = s.length() - 1, j = buf.length - 1; i >= 0; --i, --j) {
			char c = s.charAt(i);
			int charPos = chars[c];
			if (charPos < 0 || charPos >= digits.length) {
				throw new RuntimeException("out of range");
			}
			buf[j] = c;
		}
		for (int i = 0, len = buf.length; i < len; ++i) {
			char c = buf[i];
			if (c != 0) {
				if (c != digits[0]) {
					break;
				} else {
					buf[i] = 0;
				}
			}
		}
	}
	
	public void incr() {
		int posInBuf = buf.length - 1;
		char c = buf[posInBuf];
		while (c == digits[digits_length - 1]) {
			buf[posInBuf] = digits[0];
			--posInBuf;
			if (posInBuf < 0) {
				throw new RuntimeException("out of range!");
			}
			c = buf[posInBuf];
		}
		if (buf[posInBuf] == 0) {
			buf[posInBuf] = digits[1];
		} else {
			int posInDigit = chars[c];
			buf[posInBuf] = digits[posInDigit + 1];
		}
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + Arrays.hashCode(buf);
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		CharseqNumber other = (CharseqNumber) obj;
		if (!Arrays.equals(buf, other.buf))
			return false;
		return true;
	}

	public String toCharSeqString() {
		int pos = 0;
		while (buf[pos] == 0) {
			pos++;
			if (pos >= buf.length) {
				return String.valueOf(digits[0]);
			}
		}
		return new String(buf, pos, buf.length - pos);
	}
	
	public String toString() {
		return toCharSeqString();
	}

}
